package com.hjrpc.babyyamall.search.filter;

import com.hjrpc.babyyamall.search.feign.MemberFeignService;
import com.hjrpc.common.constant.AuthServerConstant;
import com.hjrpc.common.dto.LoginUserTo;
import com.hjrpc.common.utils.R;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

//@WebFilter(urlPatterns = "/*", filterName = "ssoTokenFilter")
public class SSOTokenFilter implements Filter {

    @Value("${auth.sso.url}")
    String ssoServerUrl;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    MemberFeignService memberFeignService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
        String[] array = httpRequest.getParameterMap().get("ssoToken");
        String ssoToken = null;
        if (array != null && array.length >= 1) {
            ssoToken = array[0];
        }
        if (StringUtils.isBlank(ssoToken)) {
            if (httpRequest.getCookies() != null) {
                List<Cookie> collect = Arrays.stream(httpRequest.getCookies())
                        .filter(cookie -> "ssoToken".equals(cookie.getName())).collect(Collectors.toList());
                if (!collect.isEmpty()) {
                    ssoToken = collect.get(0).getValue();
                }
            }
        }
        // 如果没有token，我们就带上请求路径重定向到
        if (StringUtils.isBlank(ssoToken)) {
            String s = "/".equals(httpRequest.getRequestURI()) ? "" : httpRequest.getRequestURI();
            String queryString = httpRequest.getQueryString();
            String encode = StringUtils.isBlank(queryString) ? "" : URLEncoder.encode(queryString, "iso-8859-1");
            String location = ssoServerUrl + "?redirectUrl=http://search.babyyamall.com" +
                    s + "?" + encode;
            httpResponse.sendRedirect(location);
        } else {
            String memberIdString = redisTemplate.opsForValue().get(AuthServerConstant.AUTH_SSO_TOKEN_PREFIX + ssoToken);
            R r = memberFeignService.info(Long.parseLong(memberIdString));
            if (r.isSuccess()) {
                LoginUserTo loginUserTo = r.getData(LoginUserTo.class);
                httpRequest.setAttribute("loginUser", loginUserTo);
                Cookie cookie = new Cookie("ssoToken", ssoToken);
                httpResponse.addCookie(cookie);
                filterChain.doFilter(servletRequest, servletResponse);
            } else {
                throw new RuntimeException("远程调用出现异常");
            }
        }
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
